import { Injectable } from '@nestjs/common';
import { ArticleContentCollectEntity } from './aritcle-content-collect.entity';
import { DataSource, Repository } from 'typeorm';
import { InjectDataSource, InjectRepository } from '@nestjs/typeorm';
import { isNil } from 'lodash';
import { ArticleContentEntity } from '../article-content.entity';
import { UserEntity } from '~/modules/user/user.entity';
import { UserWechatEntity } from '~/modules/user/user-wechat/user-wechat.entity';

@Injectable()
export class ArticleContentCollectService {
  constructor(
    @InjectRepository(ArticleContentCollectEntity)
    private readonly articleContentCollectRepo: Repository<ArticleContentCollectEntity>,
    @InjectDataSource()
    private readonly datasource: DataSource
  ) {}

  async create(contentId: number, userId: number): Promise<ArticleContentCollectEntity> {
    // Check if the content is already collected
    const existingCollection: ArticleContentCollectEntity =
      await this.articleContentCollectRepo.findOneBy({
        user: { id: userId },
        content: { id: contentId },
      });

    // If it exists, return it
    if (existingCollection) {
      return existingCollection;
    }

    return await this.articleContentCollectRepo.save({
      user: { id: userId },
      content: { id: contentId },
    });
  }

  async delete(contentId: number, userId: number): Promise<void> {
    await this.articleContentCollectRepo.delete({
      user: { id: userId },
      content: { id: contentId },
    });
  }

  async hasCollected(contentId: number, userId: number): Promise<boolean> {
    const collected: ArticleContentCollectEntity = await this.articleContentCollectRepo.findOneBy({
      user: { id: userId },
      content: { id: contentId },
    });

    return !isNil(collected);
  }

  async getCollectionByUser(userId: number): Promise<Array<Partial<ArticleContentEntity>>> {
    const collections: ArticleContentCollectEntity[] = await this.articleContentCollectRepo.find({
      where: { user: { id: userId } },
      relations: ['content'],
    });

    return collections.map((collection: ArticleContentCollectEntity) => {
      delete collection.content.content;
      delete collection.content.rawHtml;

      return collection.content;
    });
  }

  /**
   * 获取用户的收藏数量
   * @param userId 用户ID
   * @returns 用户的收藏数量
   */
  async getUserCollectCount(userId: number): Promise<number> {
    return await this.articleContentCollectRepo.count({
      where: { user: { id: userId } },
    });
  }

  /**
   * 统计数据
   * @returns
   */
  async getAllCount(): Promise<Partial<ArticleContentCollectEntity>[]> {
    return await this.datasource
      .createQueryBuilder()
      .addSelect('article_collect.created_at', 'createdAt')
      .addSelect('userWechat.nickname', 'nickname')
      .addSelect('userWechat.phone', 'phone')
      .addSelect('articleContent.code', 'articleCode')
      .addSelect('articleContent.name', 'articleName')
      .from(ArticleContentCollectEntity, 'article_collect')
      .leftJoin(UserEntity, 'user', 'user.id = article_collect.user_id')
      .leftJoin(UserWechatEntity, 'userWechat', 'userWechat.id = user.wechat_id')
      .leftJoin(
        ArticleContentEntity,
        'articleContent',
        'articleContent.id = article_collect.content_id'
      )
      .orderBy('article_collect.id', 'DESC')
      .getRawMany();
  }
}
